package com.ym.medical.service.impl;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ym.common.enums.UserUserTypeEnum;
import com.ym.common.utils.CalcUtil;
import com.ym.common.utils.HttpUtil;
import com.ym.core.config.ConfigCenterProperties;
import com.ym.core.config.QiNiuYunConfig;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.dao.ChatDetailsDao;
import com.ym.medical.domain.bo.YunxinSyncDataVo;
import com.ym.medical.domain.entity.ChatDetailsEntity;
import com.ym.medical.domain.entity.CounsellingRoomEntity;
import com.ym.medical.domain.entity.CustomerChatDetailsEntity;
import com.ym.medical.domain.entity.DoctorChatDetailsEntity;
import com.ym.medical.domain.entity.DoctorWeightEntity;
import com.ym.medical.domain.entity.InquiryOrderEntity;
import com.ym.medical.domain.entity.UserEntity;
import com.ym.medical.domain.entity.YunxinUserEntity;
import com.ym.medical.enums.DoctorWeightTypeEnum;
import com.ym.medical.enums.FileTypeEnum;
import com.ym.medical.service.IChatDetailsSV;
import com.ym.medical.service.ICounsellingRoomSV;
import com.ym.medical.service.ICustomerChatDetailsSV;
import com.ym.medical.service.IDoctorChatDetailsSV;
import com.ym.medical.service.IDoctorWeightSV;
import com.ym.medical.service.IFileInforSV;
import com.ym.medical.service.IInquiryOrderSV;
import com.ym.medical.service.IUserSV;
import com.ym.medical.service.IYunxinUserSV;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 医患聊天内容Service业务层处理
 *
 * @author ym
 * @date 2020-08-21
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ChatDetailsSVImpl extends BaseSVImpl<ChatDetailsEntity, ChatDetailsDao> implements IChatDetailsSV {

	private static final Logger LOGGER = LoggerFactory.getLogger(ChatDetailsSVImpl.class);

	@Autowired
	private IUserSV userSV;

	@Autowired
	private ICustomerChatDetailsSV customerChatDetailsSV;

	@Autowired
	private IDoctorChatDetailsSV doctorChatDetailsSV;

	@Autowired
	private IDoctorWeightSV doctorWeightSV;

	@Autowired
	private IFileInforSV fileInforSV;

	@Autowired
	private ICounsellingRoomSV counsellingRoomService;

	@Override
	public Long getChatsNums(Long courId) {
		LOGGER.info("查询聊天次数的聊天室ID为：{}", courId);
		List<ChatDetailsEntity> chatDetailsPageInfo = this.selectList(
				TK.select(ChatDetailsEntity.class).column("cds_person").where()
						.andEqualTo(ChatDetailsEntity::getCourId, courId)
						.end()
						.orderBy(ChatDetailsEntity::getCdsTime)
		);
		// 双方聊天回合数计算，
		Long doctorId = null;
		Long userId = null;
		Long beforeSendId = null;
		// 回合是否结束
		boolean done = false;
		long chatNums = 0;
		for (int i = 0; i < chatDetailsPageInfo.size(); i++) {
			ChatDetailsEntity chatDetails = chatDetailsPageInfo.get(i);
			Long cdsPerson = chatDetails.getCdsPerson();
			if (userId == null || doctorId == null) {
				// 辨别ID的类型
				UserEntity user = userSV.findById(cdsPerson);
				if (user.getUserType().equals(UserUserTypeEnum.DOCTOR.getKey())) {
					doctorId = cdsPerson;
				} else {
					userId = cdsPerson;
				}
			}
			if (done && cdsPerson.equals(userId)) {
				// 重置条件为，done为true。且发送人变化为用户
				done = false;
			}

			if (!done && cdsPerson.equals(doctorId) && userId != null) {
				// 如果发送人为医生ID，且不是第一次,则一回合结束
				done = true;
			}

			if (done && beforeSendId != null && !beforeSendId.equals(doctorId)) {
				// 表示一回合结束
				chatNums++;
			}
			if (userId != null && doctorId != null) {
				beforeSendId = cdsPerson;
			}

		}
		return chatNums;
	}

	@Override
	public void saveYunxinNews(YunxinSyncDataVo yunxinSyncDataVo) {
		IYunxinUserSV yunxinUserSV = SpringUtil.getBean(IYunxinUserSV.class);
		IInquiryOrderSV inquiryOrderSV = SpringUtil.getBean(IInquiryOrderSV.class);
		// 获取扩展消息
		String ext = yunxinSyncDataVo.getExt();
		LOGGER.info("处理单聊抄送记录");
		JSONObject extData = JSONObject.parseObject(ext);
		// 聊天场景.1医患聊天2医生聊天3客服聊天
		String chatType = extData.getString("chatType");
		// 处理云信附件
		processingAttach(yunxinSyncDataVo);
		// 发送时间
		Long msgTimestamp = Long.valueOf(yunxinSyncDataVo.getMsgTimestamp());
		//发送内容
		String content = yunxinSyncDataVo.getBody();
		String attach = yunxinSyncDataVo.getAttach();
		if (StringUtils.isBlank(chatType) || "1".equals(chatType)) {
			// 表示是医患聊天
			// 订单ID
			Long orderId = extData.getLong("orderId");
			// 聊天室主键ID
			Long counsellingRoomId = extData.getLong("counsellingRoomId");
			// 发送人
			Long sendPerson = extData.getLong("sendPerson");
			ChatDetailsEntity chatDetails = new ChatDetailsEntity();
			chatDetails.setCourId(counsellingRoomId);
			chatDetails.setCdsBody(content);
			chatDetails.setCdsTime(msgTimestamp);
			chatDetails.setAttach(attach);
			chatDetails.setCdsPerson(sendPerson);
			chatDetails.setCdsType(yunxinSyncDataVo.getMsgType());
			this.insert(chatDetails);
			InquiryOrderEntity order = inquiryOrderSV.selectById(orderId);
			// 如果是医生回复，设置医生的响应速度
			if (!order.getUserId().equals(sendPerson)) {
				setDoctorSpend(sendPerson, counsellingRoomId, msgTimestamp);
			}
		} else if ("2".equals(chatType)) {
			// 用户之间聊天
			LOGGER.info("用户聊天记录");
			DoctorChatDetailsEntity doctorChatDetails = new DoctorChatDetailsEntity();
			doctorChatDetails.setAttach(attach);
			doctorChatDetails.setCdsAccid(yunxinSyncDataVo.getFromAccount());
			doctorChatDetails.setReceiveAccid(yunxinSyncDataVo.getTo());
			doctorChatDetails.setCdsTime(msgTimestamp);
			List<YunxinUserEntity> yunxinUsers = yunxinUserSV.selectList(YunxinUserEntity.builder().accid(yunxinSyncDataVo.getTo()).build());
			if (!yunxinUsers.isEmpty()) {
				doctorChatDetails.setReceivePerson(yunxinUsers.get(0).getUserId());
			}
			yunxinUsers = yunxinUserSV.selectList(YunxinUserEntity.builder().accid(yunxinSyncDataVo.getFromAccount()).build());
			if (!yunxinUsers.isEmpty()) {
				doctorChatDetails.setCdsPerson(yunxinUsers.get(0).getUserId());
			}
			doctorChatDetails.setCdsBody(content);
			doctorChatDetails.setCdsType(yunxinSyncDataVo.getMsgType());
			doctorChatDetailsSV.insert(doctorChatDetails);
		} else if ("3".equals(chatType)) {
			// 系统用户ID
			Long sysUserId = extData.getLong("sysUserId");
			// 顾客的ID
			Long customerId = extData.getLong("customerId");
			// 顾客的云信ID
			String customerAccid = extData.getString("customerAccid");
			LOGGER.info("客服聊天");
			CustomerChatDetailsEntity customerChatDetails = new CustomerChatDetailsEntity();
			customerChatDetails.setAttach(attach);
			customerChatDetails.setSysUserId(sysUserId);
			customerChatDetails.setCustomerId(customerId);
			customerChatDetails.setCustomeAccid(customerAccid);
			customerChatDetails.setCdsTime(msgTimestamp);
			customerChatDetails.setCdsBody(content);
			customerChatDetails.setCdsType(yunxinSyncDataVo.getMsgType());
			customerChatDetailsSV.insert(customerChatDetails);
		}
	}

	/**
	 * 设置医生的响应速度
	 *
	 * @param sendPerson 医生ID
	 * @param roomId     聊天室ID
	 * @param currTime
	 */
	private void setDoctorSpend(Long sendPerson, Long roomId, final Long currTime) {
		// 查询双方聊天记录
		List<ChatDetailsEntity> list = this.selectList(
				TK.select(ChatDetailsEntity.class).orderByClause(" cds_Time desc limit 2").where()
						.andEqualTo(ChatDetailsEntity::getCourId, roomId)
						.andEqualTo(ChatDetailsEntity::getCdsPerson, sendPerson)
						.end()
		);
		// 设置本次回复耗时
		long time = currTime;
		if (!list.isEmpty() && list.size() > 1) {
			time = time - list.get(1).getCdsTime();
		}
		double dbTime = time / 1000;
		// 查询医生当前评分,设置
		DoctorWeightEntity doctorWeight = doctorWeightSV.selectOne(DoctorWeightEntity.builder().doctorId(sendPerson).build());
		if (doctorWeight == null) {
			doctorWeight = new DoctorWeightEntity();
			doctorWeight.setWeightValue(CalcUtil.init(dbTime).decimalValue(4));
			doctorWeight.setDoctorId(sendPerson);
			doctorWeight.setWeightType(DoctorWeightTypeEnum.RESPONSE_SPEED.getKey());
			doctorWeightSV.insert(doctorWeight);
		} else {
			doctorWeight.setWeightValue(CalcUtil.init(doctorWeight.getWeightValue()).add(dbTime).div(2).decimalValue(4));
			doctorWeightSV.updateById(doctorWeight);
		}
	}

	/**
	 * 处理云信的附件，转为本地
	 *
	 * @param yunxinSyncDataVo
	 * @return
	 */
	private void processingAttach(YunxinSyncDataVo yunxinSyncDataVo) {
		QiNiuYunConfig configCenterProperties = SpringUtil.getBean(ConfigCenterProperties.class).getQiNiuYunConfig();
		FileTypeEnum msgType = null;
		String showUrl = null;
		switch (yunxinSyncDataVo.getMsgType()) {
			case "PICTURE":
				msgType = FileTypeEnum.IMG;
				showUrl = configCenterProperties.getShowImageUrl();
				yunxinSyncDataVo.setBody("[图片]");
				break;
			case "AUDIO":
				msgType = FileTypeEnum.REC;
				showUrl = configCenterProperties.getShowRecUrl();
				yunxinSyncDataVo.setBody("[语音]");
				break;
			case "VIDEO":
				msgType = FileTypeEnum.VIDEO;
				showUrl = configCenterProperties.getShowVideoUrl();
				yunxinSyncDataVo.setBody("[视频]");
				break;
			case "CUSTOM":
				yunxinSyncDataVo.setBody("[语音]");
				break;
			default:
				return;
		}
		if (msgType != null) {
			String attach = yunxinSyncDataVo.getAttach();
			if (StringUtils.isBlank(attach)) {
				return;
			}
			JSONObject attachObject = JSONObject.parseObject(attach);
			if (StringUtils.isBlank(attachObject.getString("url"))) {
				return;
			}
			//三种文件，图片、语音、视频，上传七牛
			LOGGER.info("获取到云信附件地址:{}", attachObject.getString("url"));
			InputStream is = HttpUtil.get(attachObject.getString("url")).stream();
			String fileId = fileInforSV.uploadFile(is, msgType, null, "yunxin_attach", "attach", "云信推送附件", 1L);
			attachObject.put("url", showUrl + fileId);
			yunxinSyncDataVo.setAttach(attachObject.toString());
			LOGGER.info("处理云信附件{}成功", msgType);
		}
	}


	@Override
	public Map<String, Object> getChatsContent(Long roomId, int pageNum, int pageSize) {
		IInquiryOrderSV inquiryOrderSV = SpringUtil.getBean(IInquiryOrderSV.class);
		Map<String, Object> result = new HashMap<>();
		//获取订单id
		CounsellingRoomEntity counsellingRoom = counsellingRoomService.selectById(roomId);
		InquiryOrderEntity order = null;
		if (counsellingRoom != null) {
			order = inquiryOrderSV.selectById(counsellingRoom.getIoId());
			Integer readNum = order.getReadNum() == null ? 0 : order.getReadNum();
			order.setReadNum(readNum + 1);
			inquiryOrderSV.updateById(order);
			result.put("userId", order.getUserId());
		}
		PageHelper.startPage(pageNum, pageSize);
		List<ChatDetailsEntity> chatDetailsPageInfo = this.selectList(
				ChatDetailsEntity.builder().courId(roomId).build()

		);
		result.put("data", new PageInfo<>(chatDetailsPageInfo));
		return result;
	}
}
